package com.vegetable.modules.service.baseData.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vegetable.common.utils.R;
import com.vegetable.modules.entity.baseData.ProductCategory;
import com.vegetable.modules.form.ProductCategoryForm;
import com.vegetable.modules.mapper.baseData.ProductCategoryMapper;
import com.vegetable.modules.query.ProductCategoryQuery;
import com.vegetable.modules.service.baseData.IProductCategoryService;
import com.vegetable.modules.vo.ProductCategoryTreeVO;
import com.vegetable.modules.vo.ProductCategoryVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品分类服务实现类
 * </p>
 *
 * @author wangruijie
 * @since 2024-12-10
 */
@Slf4j
@Service
public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryMapper, ProductCategory> implements IProductCategoryService {

    @Override
    public IPage<ProductCategoryVO> getPageList(ProductCategoryQuery query) {
        Page<ProductCategoryVO> page = new Page<>(query.getPage(), query.getLimit());
        return baseMapper.selectCategoryPage(page, query);
    }

    @Override
    public List<ProductCategoryTreeVO> getCategoryTree() {
        // 获取所有启用的分类
        List<ProductCategory> allCategories = baseMapper.selectAllEnabled();
        
        // 构建树形结构
        return buildTree(allCategories, 0L);
    }

    @Override
    public List<ProductCategory> getChildrenByParentId(Long parentId) {
        return baseMapper.selectByParentId(parentId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R addCategory(ProductCategoryForm form) {
        // 验证分类编码是否唯一
        if (!isCategoryCodeUnique(form.getCategoryCode(), null)) {
            return R.fail("分类编码已存在");
        }

        // 验证父分类是否存在
        if (form.getParentId() != 0) {
            ProductCategory parent = getById(form.getParentId());
            if (parent == null) {
                return R.fail("父分类不存在");
            }
            if (parent.getLevel() >= 3) {
                return R.fail("最多支持3级分类");
            }
        }

        ProductCategory category = new ProductCategory();
        BeanUtils.copyProperties(form, category);
        
        // 设置层级
        if (form.getParentId() == 0) {
            category.setLevel(1);
        } else {
            ProductCategory parent = getById(form.getParentId());
            category.setLevel(parent.getLevel() + 1);
        }

        // 设置排序
        if (form.getSortOrder() == null) {
            Integer maxSort = baseMapper.selectMaxSortOrder(form.getParentId());
            category.setSortOrder(maxSort + 1);
        }

        // 设置默认值
        if (category.getIsEnabled() == null) {
            category.setIsEnabled(1);
        }

        // TODO: 设置创建用户ID，这里先使用默认值
        category.setCreateUserId(1L);

        boolean success = save(category);
        return success ? R.success("添加成功") : R.fail("添加失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R updateCategory(ProductCategoryForm form) {
        if (form.getId() == null) {
            return R.fail("分类ID不能为空");
        }

        ProductCategory existCategory = getById(form.getId());
        if (existCategory == null) {
            return R.fail("分类不存在");
        }

        // 验证分类编码是否唯一
        if (!isCategoryCodeUnique(form.getCategoryCode(), form.getId())) {
            return R.fail("分类编码已存在");
        }

        // 验证父分类
        if (form.getParentId() != 0) {
            if (form.getParentId().equals(form.getId())) {
                return R.fail("不能将自己设为父分类");
            }
            
            // 检查是否会形成循环
            if (isCircularReference(form.getId(), form.getParentId())) {
                return R.fail("不能将子分类设为父分类");
            }
        }

        ProductCategory category = new ProductCategory();
        BeanUtils.copyProperties(form, category);
        
        // 重新计算层级
        if (form.getParentId() == 0) {
            category.setLevel(1);
        } else {
            ProductCategory parent = getById(form.getParentId());
            category.setLevel(parent.getLevel() + 1);
        }

        // TODO: 设置更新用户ID
        category.setUpdateUserId(1L);

        boolean success = updateById(category);
        return success ? R.success("更新成功") : R.fail("更新失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R deleteCategory(Long id) {
        ProductCategory category = getById(id);
        if (category == null) {
            return R.fail("分类不存在");
        }

        // 检查是否有子分类
        Integer childCount = baseMapper.countByParentId(id);
        if (childCount > 0) {
            return R.fail("存在子分类，无法删除");
        }

        // TODO: 检查是否有商品使用此分类
        // 这里需要查询products表，暂时跳过

        boolean success = removeById(id);
        return success ? R.success("删除成功") : R.fail("删除失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R enableCategory(Long id, Integer isEnabled) {
        ProductCategory category = getById(id);
        if (category == null) {
            return R.fail("分类不存在");
        }

        category.setIsEnabled(isEnabled);
        category.setUpdateUserId(1L);
        category.setUpdateTime(LocalDateTime.now());

        boolean success = updateById(category);
        return success ? R.success("操作成功") : R.fail("操作失败");
    }

    @Override
    public ProductCategoryVO getCategoryDetail(Long id) {
        ProductCategory category = getById(id);
        if (category == null) {
            return null;
        }

        ProductCategoryVO vo = new ProductCategoryVO();
        BeanUtils.copyProperties(category, vo);

        // 获取父分类名称
        if (category.getParentId() != 0) {
            ProductCategory parent = getById(category.getParentId());
            if (parent != null) {
                vo.setParentName(parent.getCategoryName());
            }
        }

        return vo;
    }

    @Override
    public ProductCategory getByCategoryCode(String categoryCode) {
        return baseMapper.selectByCategoryCode(categoryCode);
    }

    @Override
    public boolean isCategoryCodeUnique(String categoryCode, Long excludeId) {
        LambdaQueryWrapper<ProductCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductCategory::getCategoryCode, categoryCode);
        if (excludeId != null) {
            wrapper.ne(ProductCategory::getId, excludeId);
        }
        return count(wrapper) == 0;
    }

    @Override
    public List<ProductCategory> getTopCategories() {
        LambdaQueryWrapper<ProductCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductCategory::getParentId, 0)
                .eq(ProductCategory::getIsEnabled, 1)
                .orderByAsc(ProductCategory::getSortOrder);
        return list(wrapper);
    }

    @Override
    public List<ProductCategory> searchByName(String categoryName) {
        return baseMapper.selectByCategoryNameLike(categoryName);
    }

    /**
     * 构建树形结构
     */
    private List<ProductCategoryTreeVO> buildTree(List<ProductCategory> categories, Long parentId) {
        List<ProductCategoryTreeVO> tree = new ArrayList<>();
        
        for (ProductCategory category : categories) {
            if (category.getParentId().equals(parentId)) {
                ProductCategoryTreeVO node = new ProductCategoryTreeVO();
                BeanUtils.copyProperties(category, node);
                
                // 递归查找子节点
                List<ProductCategoryTreeVO> children = buildTree(categories, category.getId());
                node.setChildren(children);
                node.setHasChildren(!CollectionUtils.isEmpty(children));
                
                tree.add(node);
            }
        }
        
        // 按排序字段排序
        tree.sort((a, b) -> a.getSortOrder().compareTo(b.getSortOrder()));
        
        return tree;
    }

    /**
     * 检查是否会形成循环引用
     */
    private boolean isCircularReference(Long categoryId, Long parentId) {
        if (parentId == 0) {
            return false;
        }
        
        ProductCategory parent = getById(parentId);
        if (parent == null) {
            return false;
        }
        
        if (parent.getId().equals(categoryId)) {
            return true;
        }
        
        return isCircularReference(categoryId, parent.getParentId());
    }
}